package com.shanxia.codec.cmd;

import com.shanxia.codec.Decoder;
import com.shanxia.codec.ProtocolDataBase;
import lombok.Data;

import java.math.BigDecimal;
import java.util.Arrays;

import static com.shanxia.codec.Decoder.*;

/**
 * C -> S
 * 充电桩上传心跳包信息
 * 充电桩定期发送该指令向服务器传递连接心跳包信息
 */
@Data
public class Cmd102 extends ProtocolDataBase {

    public static final int MIN_SIZE = 54;

    private int v1;
    private int v2;
    private String sn;                        //充电桩编码
    private int heartSequence;                //心跳序号
    private int[] pileStatus = new int[128];  //各枪状态  HEX，每位代表一个枪，可表示 1~128 枪的状态：0-未插入枪、1-已插枪

    public Cmd102(){
        super.setCmd(102);
    }

    public static Cmd102 decodeFromBase(ProtocolDataBase protocolDataBase) {
        Cmd102 cmd = new Cmd102();
        cmd.copyDataFrom(protocolDataBase);
        int offset = 0;
        cmd.v1 = Decoder.getUint16(protocolDataBase.getDataField(), offset);
        offset += 2;
        cmd.v2 = Decoder.getUint16(protocolDataBase.getDataField(), offset);
        offset += 2;
        // 32字节充电桩编码
        cmd.sn = Decoder.byteToAscii(Arrays.copyOfRange(protocolDataBase.getDataField(), offset, offset + 32), true);
        offset += 32;
        // 2字节心跳序号
        cmd.heartSequence = Decoder.getUint16(protocolDataBase.getDataField(), offset);
        offset += 2;
        // 16字节各枪状态
        // 状态是按bit计算而不是字节
        byte[] statusbytes = Arrays.copyOfRange(protocolDataBase.getDataField(), offset, offset + 16);
        for (int i = 0; i < 16; i ++) {
            for (int j = 0; j < 8; j ++) {
                cmd.pileStatus[8 * i + j] = Decoder.getBits(statusbytes[i], j, 1);
            }
        }
        return cmd;
    }

    /**
     * 测试 102 时使用该方法
     * @return
     */
    @Override
    public byte[] getDataField() {
        int offset = 0;
        byte[] data = new byte[MIN_SIZE];
        getBytesAsUint16(data, offset, this.v1);
        offset += 2;
        getBytesAsUint16(data, offset, this.v2);
        offset += 2;
        // 32字节用户卡号/用户识别号
        encodeAscii(data, sn, 32, offset);
        offset += 32;

        // 心跳序号
        getBytesAsUint16(data, offset, this.heartSequence);
        offset += 2;

        //各枪状态
        int[] pileStatus = new int[128];
        for(int i=0; i<16; i++){
            int bt = 0;
            for(int j=0; j<8; j++){
                int temp = 0;
                temp |= pileStatus[8 * i + j] & 0x0F;
                temp <<= j;
                bt |= temp;
            }
            data[offset++] = (byte)bt;
        }

        return data;
    }

    @Override
    public String toString() {

        StringBuffer buffer = new StringBuffer();
        buffer.append("#cmd102#").append("\n");
        buffer.append("v1:").append(v1).append("\n");
        buffer.append("v2:").append(v2).append("\n");
        buffer.append("充电桩编码:").append(sn).append("\n");
        buffer.append("心跳序号:").append(heartSequence).append("\n");
        buffer.append("128个各枪状态:").append(pileStatus).append("\n");
        return buffer.toString();
    }
}
